#include "dht11.h"

int dht11_val[5]={0,0,0,0,0};

int dht11_read_val( struct dht11_result *result)
{
    uint8_t lststate=HIGH;         //last state
    uint8_t counter=0;
    uint8_t j=0,i;

    if (result == NULL)
        return 0;
    for(i=0;i<5;i++)
        dht11_val[i]=0;

    //host send start signal
    pinMode(DHT11PIN,OUTPUT);      //set pin to output
    digitalWrite(DHT11PIN,LOW);    //set to low at least 18ms
    delay(18);
    digitalWrite(DHT11PIN,HIGH);   //set to high 20-40us
    delayMicroseconds(40);

    //start recieve dht response
    pinMode(DHT11PIN,INPUT);       //set pin to input
    for(i=0;i<MAX_TIME;i++){
        counter=0;
        while(digitalRead(DHT11PIN)==lststate){     //read pin state to see if dht responsed. if dht always high for 255 + 1 times, break this while circle
            counter++;
            delayMicroseconds(1);
            if(counter==255)
                break;
        }
        lststate=digitalRead(DHT11PIN);             //read current state and store as last state.
        if(counter==255)                            //if dht always high for 255 + 1 times, break this for circle
            break;
        // top 3 transistions are ignored, maybe aim to wait for dht finish response signal
        if((i>=4)&&(i%2==0)){
            dht11_val[j/8]<<=1;                     //write 1 bit to 0 by moving left (auto add 0)
            if(counter>16)                          //long mean 1
                dht11_val[j/8]|=1;                  //write 1 bit to 1
            j++;
        }
    }
    // verify checksum and print the verified data
    if((j>=40)&&(dht11_val[4]==
                 ((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))){
        result->tempture = dht11_val[2];
        result->humidity = dht11_val[0];
        return 1;
    }else
        return 0;
}

/*
 *  read tempture and hundity form DHT11 sensor.
 *  if read or, will return 1; eles return 0.
 */
int  read_dht11(struct dht11_result* result)
{
    int i;
    for (i = 0; i < ATTEMPTS; ++i){
            if (dht11_read_val(result) != 0)
                    return 1;
            delay(2000);
    }
    return 0;
}
